/*
 * @Author: 码农 2646995216@qq.com
 * @Date: 2025-03-04 23:50:49
 * @LastEditors: 码农 2646995216@qq.com
 * @LastEditTime: 2025-03-07 12:13:23
 * @FilePath: /pthread/BlockQueue.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include<iostream>
#include<pthread.h>
#include<queue>

using namespace std;

template<class T>
class BlockQueue
{
public:
    //初始化
	BlockQueue(int max=20)
	:_max(max)
	{
		
		pthread_cond_init(&_cond1,nullptr);
		pthread_cond_init(&_cond2,nullptr);
		pthread_mutex_init(&_mutex,nullptr);
	}
    
	//头删，并且返回这个数，生产者使用的接口
	T pop()
	{
		pthread_mutex_lock(&_mutex);//加锁
		while(_q.size()==0)//如果队列中没有数据，则让线程等待
		{
			pthread_cond_wait(&_cond1,&_mutex);
		}
		T data=_q.front();
        _q.pop();
        
		pthread_cond_signal(&_cond2);//唤醒正在等待的尾插线程，可以插入了
		pthread_mutex_unlock(&_mutex);//解锁
		return data;
	}
   
	//尾插，消费者使用的接口
	void push(T& data)
	{
		pthread_mutex_lock(&_mutex);//加锁
		while(_q.size()==_max)//如果队列中数据满了，则让线程等待
		{
				pthread_cond_wait(&_cond2,&_mutex);
		}
		_q.push(data);

        pthread_cond_signal(&_cond1);//唤醒正在等待的头删线程，可以删除了
        pthread_mutex_unlock(&_mutex);//解锁
	}


    //销毁
	~BlockQueue()
	{
		pthread_cond_destroy(&_cond1);
		pthread_cond_destroy(&_cond2);
		pthread_mutex_destroy(&_mutex);
	}

private:
	pthread_cond_t _cond1;//头删条件变量
	pthread_cond_t _cond2;//尾插条件变量
	pthread_mutex_t _mutex;//定义锁
    queue<T> _q;//定义队列
	int _max;//队列的空间大小
};



